import G6 from '@antv/g6'
import { useEffect, useState } from 'react'

// 辅助函数：将点数组转换为G6 path格式
function getPathFromPoints(points) {
  const pathCommands = []
  // 第一个点使用'M'（移动到）
  pathCommands.push(['M', points[0][0], points[0][1]])
  // 其余的点使用'L'（画线到）
  for (let i = 1; i < points.length; i++) {
    pathCommands.push(['L', points[i][0], points[i][1]])
  }
  return pathCommands
}

export default function Home() {
  const data: any = {
    nodes: [
      {
        title: 'Fragament-5',
        id: '0',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=312',
              time: '14ms 223ns',
              progress: '5.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=123',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ]
        ]
      },
      {
        title: 'Fragament-5',
        id: '1',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'EXCHANGE',
              label: 'Plan_node_id=35',
              time: '14ms 223ns',
              progress: '19.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=312',
              time: '14ms 223ns',
              progress: '5.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=213',
              time: '14ms 223ns',
              progress: '6.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=123',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'right',
              active: false,
              hover: false
            }
          ]
        ]
      },
      {
        title: 'Fragament-6',
        id: '2',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'EXCHANGE',
              label: 'Plan_node_id=35',
              time: '14ms 223ns',
              progress: '19.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=123',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=312',
              time: '14ms 223ns',
              progress: '5.00',
              type: 'left',
              active: false,
              hover: false
            }
          ]
        ]
      },
      {
        title: 'Fragament-6',
        id: '3',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'EXCHANGE',
              label: 'Plan_node_id=35',
              time: '14ms 223ns',
              progress: '19.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=123',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ]
        ]
      },
      {
        title: 'Fragament-6',
        id: '4',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'EXCHANGE',
              label: 'Plan_node_id=35',
              time: '14ms 223ns',
              progress: '19.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=312',
              time: '14ms 223ns',
              progress: '5.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=213',
              time: '14ms 223ns',
              progress: '6.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=213',
              time: '14ms 223ns',
              progress: '6.00',
              type: 'right',
              active: false,
              hover: false
            }
          ]
        ]
      },
      {
        title: 'Fragament-6',
        id: '5',
        children: [
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'center',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=3',
              time: '14ms 223ns',
              progress: '1.00',
              type: 'left',
              active: false,
              hover: false
            },
            {
              title: 'EXCHANGE',
              label: 'Plan_node_id=35',
              time: '14ms 223ns',
              progress: '19.00',
              type: 'right',
              active: false,
              hover: false
            }
          ],
          [
            {
              title: 'AGGREGATION',
              label: 'Plan_node_id=312',
              time: '14ms 223ns',
              progress: '5.00',
              type: 'left',
              active: false,
              hover: false
            }
          ]
        ]
      }
    ],
    edges: []
  }

  const [graphRef, setGraphRef] = useState(null)

  G6.registerNode(
    'kingCard',
    {
      options: {
        style: {},
        stateStyles: {
          hover: {},
          selected: {}
        }
      },
      draw(cfg: any, group) {
        const radius = 4
        const rectWidth = 200
        const edgeH = 114

        const maxWidth = cfg.children?.reduce((prev, item) => {
          prev = item.length > prev ? item.length : prev
          return prev
        }, 1)
        const cardHeight =
          rectWidth * 0.56 * cfg.children.length + cfg.children.length * edgeH

        // 外层盒子
        const keyShape = group.addShape('rect', {
          attrs: {
            // x: cfg.x,
            // y: cfg.y,
            width: rectWidth * maxWidth + 20 * (maxWidth + 1),
            height: cardHeight,
            radius: [radius, radius, radius, radius],
            lineWidth: 1,
            // stroke: '#1890ff',
            fill: '#fff',
            shadowOffsetX: 2,
            shadowOffsetY: 2,
            shadowBlur: 14
          },
          name: 'kingCard',
          draggable: true
        })

        // 标题
        group.addShape('text', {
          attrs: {
            x: 14,
            y: 28,
            text: `${cfg.title}`,
            fontSize: 16,
            lineHeight: 18,
            fill: '#333'
          },
          name: 'card-title'
        })

        cfg.children.forEach((row, index) => {
          const baseX = 20
          const baseY =
            48 + index * (rectWidth * 0.56 + (index > 0 ? 96 + 24 : 0))

          row.forEach((item, idx) => {
            // const startX = baseX + idx * (rectWidth + 20)
            let startX
            if (item.type === 'center' && maxWidth === 1) {
              startX = baseX
            }
            if (item.type === 'center' && maxWidth === 2) {
              startX = baseX + rectWidth * 0.5
            }
            if (item.type === 'left') {
              startX = baseX
            }
            if (item.type === 'right') {
              startX = baseX + (rectWidth + 20)
            }
            const startY = baseY

            group.addShape('rect', {
              attrs: {
                x: startX,
                y: startY,
                width: rectWidth,
                height: rectWidth * 0.56,
                radius: [radius, radius, radius, radius],
                lineWidth: 1,
                // stroke: '#1890ff',
                fill: item.active ? '#1890ff' : item.hover ? '#1890ff' : '#fff',
                shadowColor: '#666',
                shadowOffsetX: 2,
                shadowOffsetY: 2,
                shadowBlur: 14
              },
              name: `child_${index}_${idx}`,
              draggable: true
            })

            const lastList = cfg.children[index - 1] || []
            console.log(item.siblingActive, 'item.siblingActive')
            console.log(item.siblingType, 'item.siblingType')

            const edgeColor = item.active
              ? '#1890ff'
              : item.siblingActive
              ? '#1890ff'
              : item.hover
              ? '#1890ff'
              : item.siblingHover
              ? '#1890ff'
              : '#333'

            const addEdge = (points, edgeColor) => {
              if (edgeColor === '#333') {
                group.addShape('path', {
                  attrs: {
                    startArrow: {
                      path: 'M 0,0 L 10,5 L 10,-5 Z',
                      fill: edgeColor
                    },
                    path: getPathFromPoints(points),
                    stroke: edgeColor,
                    lineWidth: 2,
                    lineAppendWidth: 5
                  },
                  name: `polyline-path-${index}-${idx}`
                })
              }
              if (edgeColor !== '#333') {
                setTimeout(() => {
                  group.addShape('path', {
                    attrs: {
                      startArrow: {
                        path: 'M 0,0 L 10,5 L 10,-5 Z',
                        fill: edgeColor
                      },
                      path: getPathFromPoints(points),
                      stroke: edgeColor,
                      lineWidth: 2,
                      lineAppendWidth: 5
                    },
                    name: `polyline-path-${index}-${idx}`
                  })
                })
              }
            }

            const fatherHasSameType = lastList.find((f) => f.type === item.type)
            const fatherIsCenter = lastList.find((f) => f.type === 'center')
            if (fatherHasSameType) {
              const points = cfg.points || [
                [startX + rectWidth * 0.5, startY - edgeH],
                [startX + rectWidth * 0.5, startY]
              ]
              addEdge(points, edgeColor)
            }
            if (!fatherHasSameType) {
              if (item.type === 'left' && fatherIsCenter) {
                const rightPoints = cfg.points || [
                  [startX + rectWidth + 10, startY - edgeH],
                  [startX + rectWidth + 10, startY - 60],
                  [startX + rectWidth * 0.5, startY - 60],
                  [startX + rectWidth * 0.5, startY]
                ]
                addEdge(rightPoints, edgeColor)
              }
              if (item.type === 'right' && fatherIsCenter) {
                const leftPoints = cfg.points || [
                  [startX - 10, startY - edgeH],
                  [startX - 10, startY - 60],
                  [startX + rectWidth * 0.5, startY - 60],
                  [startX + rectWidth * 0.5, startY]
                ]
                addEdge(leftPoints, edgeColor)
              }
            }
            if (item.type === 'center' && lastList.length === 2) {
              const leftPoints = cfg.points || [
                [startX - 10, startY - edgeH],
                [startX - 10, startY - 60],
                [startX + rectWidth * 0.5, startY - 60],
                [startX + rectWidth * 0.5, startY]
              ]
              const leftEdgeColor = item.active
                ? '#1890ff'
                : item.siblingActive && item.siblingType.includes('left')
                ? '#1890ff'
                : item.hover
                ? '#1890ff'
                : item.siblingHover && item.siblingType.includes('left')
                ? '#1890ff'
                : '#333'
              addEdge(leftPoints, leftEdgeColor)

              const rightPoints = cfg.points || [
                [startX + rectWidth + 10, startY - edgeH],
                [startX + rectWidth + 10, startY - 60],
                [startX + rectWidth * 0.5, startY - 60],
                [startX + rectWidth * 0.5, startY]
              ]
              const rightEdgeColor = item.active
                ? '#1890ff'
                : item.siblingActive && item.siblingType.includes('right')
                ? '#1890ff'
                : item.hover
                ? '#1890ff'
                : item.siblingHover && item.siblingType.includes('right')
                ? '#1890ff'
                : '#333'
              addEdge(rightPoints, rightEdgeColor)
            }
          })
        })

        return keyShape
      },
      afterDraw(cfg: any, group) {
        cfg.children.forEach((row, index) => {
          row.forEach((item, idx) => {
            const childCard = group.find(
              (element) => element.get('name') === `child_${index}_${idx}`
            )

            childCard.on('click', (e) => {
              item.active = !item.active
              const nextList = cfg.children[index + 1] || []
              const sibling = nextList.find(
                (i) => i.type === item.type || i.type === 'center'
              )
              if (sibling) {
                sibling.siblingType = sibling.siblingType || []
                sibling.siblingActive = item.active
                if (!sibling.siblingType.includes(item.type)) {
                  sibling.siblingType.push(item.type)
                }
              }
              if (item.type === 'center') {
                nextList.forEach((nextItem) => {
                  nextItem.siblingType = nextItem.siblingType || []
                  nextItem.siblingActive = item.active
                  if (!nextItem.siblingType.includes(item.type)) {
                    nextItem.siblingType.push(item.type)
                  }
                })
              }
              graphRef.data(data)
              graphRef.refreshItem(cfg.id, cfg)
            })
            childCard.on('mouseenter', (e) => {
              if (!item.hover) {
                const nextList = cfg.children[index + 1] || []
                const sibling = nextList.find(
                  (i) => i.type === item.type || i.type === 'center'
                )
                if (sibling) {
                  sibling.siblingHover = true
                  sibling.siblingType = sibling.siblingType || []
                  if (!sibling.siblingType.includes(item.type)) {
                    sibling.siblingType.push(item.type)
                  }
                }
                if (item.type === 'center') {
                  nextList.forEach((nextItem) => {
                    nextItem.siblingHover = true
                    nextItem.siblingType = nextItem.siblingType || []
                    if (!nextItem.siblingType.includes(item.type)) {
                      nextItem.siblingType.push(item.type)
                    }
                  })
                }
                item.hover = true
                graphRef.data(data)
                graphRef.refreshItem(cfg.id, cfg)
              }
            })
            childCard.on('mouseleave', (e) => {
              if (item.hover) {
                const nextList = cfg.children[index + 1] || []
                const sibling = nextList.find(
                  (i) => i.type === item.type || i.type === 'center'
                )
                if (sibling) {
                  sibling.siblingHover = false
                  sibling.siblingType = sibling.siblingType || []
                  if (!item.active) {
                    sibling.siblingType = sibling.siblingType.filter(
                      (sT) => sT !== item.type
                    )
                  }
                }
                if (item.type === 'center') {
                  nextList.forEach((nextItem) => {
                    nextItem.siblingHover = false
                    nextItem.siblingType = nextItem.siblingType || []
                    if (!item.active) {
                      nextItem.siblingType = nextItem.siblingType.filter(
                        (sT) => sT !== item.type
                      )
                    }
                  })
                }
                item.hover = false
                graphRef.data(data)
                graphRef.refreshItem(cfg.id, cfg)
              }
            })
          })
        })
      },
      afterUpdate(cfg, item) {
        item.draw()
      }
    },
    'rect'
  )

  const render = () => {
    const width = 2560
    const height = 1400

    const graph = new G6.Graph({
      container: 'container',
      width,
      height,
      // translate the graph to align the canvas's center, support by v3.5.1
      fitCenter: true,
      fitView: true,
      modes: {
        default: ['drag-node']
      },
      defaultNode: {
        type: 'kingCard'
      }
    })

    // graph.data(data)
    // graph.render()
    setGraphRef(graph)
  }

  useEffect(() => {
    console.log(graphRef, '=====')
    if (graphRef) {
      graphRef.data(data)
      graphRef.render()
    }
  }, [graphRef])

  useEffect(() => {
    render()
  }, [])
  return (
    <div>
      <div>我是G6</div>
      <div id="container" style={{ background: '#f0f0f0' }}></div>
    </div>
  )
}
